﻿// This is an open source non-commercial project. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com

// ReSharper disable CheckNamespace
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable CommentTypo
// ReSharper disable IdentifierTypo
// ReSharper disable InconsistentNaming
// ReSharper disable StringLiteralTypo
// ReSharper disable UnusedParameter.Local

/*
 * Ars Magna project, http://arsmagna.ru
 */

#region Using directives

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;

#endregion

#nullable enable

namespace AM.Reporting.Functions
{
    internal class NumToWordsDe : NumToWordsBase
    {
        private static Dictionary<string, CurrencyInfo> currencyList;

        private static string[] fixedWords =
        {
            "", "ein", "zwei", "drei", "vier", "fünf", "sechs",
            "sieben", "acht", "neun", "zehn", "elf",
            "zwölf", "dreizehn", "vierzehn", "fünfzehn",
            "sechzehn", "siebzehn", "achtzehn", "neunzehn"
        };

        private static string[] tens =
        {
            "", "zehn", "zwanzig", "dreißig", "vierzig", "fünfzig",
            "sechzig", "siebzig", "achtzig", "neunzig"
        };

        private static string[] hunds =
        {
            "", "einhundert", "zweihundert", "dreihundert", "vierhundert",
            "fünfhundert", "sechshundert", "siebenhundert", "achthundert", "neunhundert"
        };

        private static WordInfo thousands = new WordInfo (false, "tausend", "tausend", "tausend");
        private static WordInfo millions = new WordInfo (false, "Million", "Millionen", "Millionen");
        private static WordInfo milliards = new WordInfo (false, "Milliarde", "Milliarden", "Milliarden");
        private static WordInfo trillions = new WordInfo (false, "Billion", "Billionen", "Billionen");

        protected override string Str1000 (long value, WordInfo info, int counter)
        {
            var val = value % 1000;
            if (val == 0)
            {
                return "";
            }

            var r = new StringBuilder();

            // add hundred
            var hund = GetHund (info.male, val);
            if (hund != "")
            {
                r.Append (hund);
            }

            val = val % 100;
            if (val < GetFixedWordsCount())
            {
                // val is less than fixed words count (usually 20), get fixed words
                var frac20 = GetFixedWords (info.male, val);
                if (frac20 != "")
                {
                    r.Append (frac20);
                }
            }
            else
            {
                // val is greater than fixed words count (usually 20), get tens separately
                var ten = GetTen (info.male, val / 10);
                var frac10 = GetFixedWords (info.male, val % 10);

                // decide whether to use 10-1 separator or not
                if (ten != "" && frac10 != "")
                {
                    r.Append (frac10 + "und" + ten);
                }
                else if (ten != "")
                {
                    r.Append (ten);
                }
                else if (frac10 != "")
                {
                    r.Append (frac10);
                }
            }

            var separator = counter == 2 ? "" : " "; // thousands do not use separator

            // add currency/group word
            r.Append (separator);
            r.Append (Case (value, info));

            // make the result starting with letter and ending with space
            if (r.Length != 0)
            {
                r.Append (separator);
            }

            return r.ToString().TrimStart (' ');
        }


        protected override string GetFixedWords (bool male, long value)
        {
            var result = fixedWords[value];
            if (!male)
            {
                if (value == 1)
                {
                    return "eine";
                }
            }

            return result;
        }

        protected override string GetTen (bool male, long value)
        {
            return tens[value];
        }

        protected override string GetHund (bool male, long value)
        {
            return hunds[value / 100];
        }

        protected override WordInfo GetThousands()
        {
            return thousands;
        }

        protected override WordInfo GetMillions()
        {
            return millions;
        }

        protected override WordInfo GetMilliards()
        {
            return milliards;
        }

        protected override WordInfo GetTrillions()
        {
            return trillions;
        }

        protected override CurrencyInfo GetCurrency (string currencyName)
        {
            currencyName = currencyName.ToUpper();
            if (currencyName == "CAD")
            {
                currencyName = "USD";
            }

            return currencyList[currencyName];
        }

        protected override string GetZero()
        {
            return "null";
        }

        protected override string GetMinus()
        {
            return "minus";
        }

        protected override string GetDecimalSeparator()
        {
            return "und ";
        }

        static NumToWordsDe()
        {
            currencyList = new Dictionary<string, CurrencyInfo>();
            currencyList.Add ("USD", new CurrencyInfo (
                new WordInfo ("Dollar", "Dollar"),
                new WordInfo ("Cent", "Cent")));
            currencyList.Add ("EUR", new CurrencyInfo (
                new WordInfo ("Euro", "Euro"),
                new WordInfo ("Cent", "Cent")));
            currencyList.Add ("GBP", new CurrencyInfo (
                new WordInfo ("Pfund", "Pfund"),
                new WordInfo ("Penny", "Penny")));
        }
    }
}
